package com.biao.transaction.example.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.biao.transaction.example.entity.OperateA;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author chenwenbiao
 * @since 2020-04-23
 */
public interface OperateAService extends IService<OperateA> {


    // 下面是OperateAService和OperateBService都没有@Transactional注解，那么它们的方法使用的是非事务的方式执行，由数据库设置的自动提交的方式来更新数据库。
    /**
     * @description: OperateAService没有@Transactional注解，它里面调用的OperateBService对象的方法（该方法没有加@Transactional注解）
     * 测试发现，不管OperateAService方法发生异常还是OperateBService对象方法抛出异常时，只要不是调用数据库的方法异常，那么这个数据库操作就会被提交，
     * 即使用了数据库自动提交的功能。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aNoTransationBNoTransation(String name);




    // 下面是OperateAService有@Transactional注解，而OperateBService方法添加或没添加@Transactional，方法的调用，两对象的方法是在同一事务里面

    /**
     * @description: OperateAService有@Transactional注解，它里面调用的OperateBService对象的方法（该方法没有加@Transactional注解）
     * 测试发现，当OperateBService对象方法抛出异常时，OperateAService和OperateBService操作都会回滚。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationBNoTransation(String name);

    /**
     * @description: OperateAService有@Transactional注解，它里面调用的OperateBService对象的方法（该方法没有加@Transactional注解）
     * 测试发现，当OperateAService对象方法抛出异常时，OperateAService和OperateBService操作都会回滚，
     * 由aTransationBNoTransation和aTransationBNoTransation2两方法测试得出结论：两方法是在同一个事务里面。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationBNoTransation2(String name);

    /**
     * @description: OperateAService有@Transactional注解，它里面调用的OperateBService对象的方法（该方法没有加@Transactional注解）
     * 测试发现：当OperateBService对象方法抛出异常时，并被处理掉，没有影响到OperateAService方法时，OperateAService和OperateBService两者操作皆不会回滚，
     * 即两方法还是在一个事务里执行。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationBNoTransationWithTryCatch(String name);




    // 下面是OperateAService没有@Transactional注解，而OperateBService方法添加@Transactional，
    // OperateAService使用非事务的sqlsession执行，而OperateBService方法是使用事务的方式执行，两者相对独立
    /**
     * @description: OperateAService没有@Transactional注解，它里面调用的OperateBService对象的方法（该方法添加了@Transactional注解）
     * 测试发现：当OperateBService对象方法抛出异常时，OperateAService操作数据库成功，OperateBService操作数据库失败。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aNoTransationBTransation(String name);

    /**
     * @description: OperateAService没有@Transactional注解，它里面调用的OperateBService对象的方法（该方法添加了@Transactional注解）
     * 测试发现：当OperateAService对象方法抛出异常时，OperateAService操作数据库成功，OperateBService操作数据库也成功。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aNoTransationBTransation2(String name);


    // 下面是OperateAService和OperateBService方法都有@Transactional注解，那么OperateBService方法会沿用OperateAService方法的事务，它们中随意一方法出现未处理异常，皆会导致两方法数据库操作回滚。
    /**
     * @description: OperateAService有@Transactional注解，它里面调用的OperateBService对象的方法（该方法也添加了@Transactional注解）
     * 测试发现：当OperateBService对象方法抛出异常时，OperateAService和OperateBService两者操作皆回滚，
     * 即两方法是在一个事务里执行，任一方法异常没处理都会回滚。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationBTransation(String name);

    /**
     * @description: OperateAService有@Transactional注解，它里面调用的OperateBService对象的方法（该方法也添加了@Transactional注解）
     * 测试发现：当OperateBService对象方法抛出异常时，并被处理掉，没有影响到OperateAService方法时，OperateAService和OperateBService两者操作皆回滚，
     * 原因：perateBService对象方法要求原子性操作，而它出现异常，所以它会回滚，而OperateAService和OperateBService都是同属一个事务，所以皆回滚。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationBTransationWithTryCatch(String name);




    // 下面是OperateAService有@Transactional注解，而OperateBService方法添加@Transactional(propagation = Propagation.REQUIRES_NEW)
    /**
     * @description: OperateAService有@Transactional注解，它里面调用的OperateBService对象的方法（该方法添加了@Transactional(propagation = Propagation.REQUIRES_NEW)注解）
     * 测试发现：当OperateBService对象方法抛出异常时，它的是新建了一个事务，所以它的数据库操作会回滚，而OperateAService的方法没有异常，所以数据库操作成功。
     * 即两方法在不同的事务里执行。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationBNewTransation(String name);

    /**
     * @description: OperateAService中一个方法有@Transactional注解，它里面调用本对象的另一方法（该方法添加了@Transactional(propagation = Propagation.REQUIRES_NEW)注解）
     * 测试发现：当第二个方法抛出异常时，且被处理掉，两方法操作都成功，它们是在一个事务里面执行，@Transactional(propagation = Propagation.REQUIRES_NEW)注解并未生效。
     * 原因，spring事务注解是通过代理对象来实现的，所以不能直接拿类对象的方法直接调用，不然它并没有使用到事务注解的特性，而是作为普通的方法，相当于没有事务注解的方法。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationANewTransation(String name);


    /**
     * @description: OperateAService中一个方法有@Transactional注解，它里面调用本对象的另一方法（该方法添加了@Transactional(propagation = Propagation.REQUIRES_NEW)注解）
     * 测试发现：使用代理对象的方式拿到事务操作对象才能使用到本类对象的事务注解的特性，所以被调用方法会新建一个事务，它的操作结果对调用者的事务不影响，
     * 所以调用者执行成功，被调用者事务回滚。
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aTransationANewTransationRightCall(String name);

    /**
     * @description: 内部调用的方法
     * @author:chenwenbiao
     * @createTime:2020-04-23
     * @version：1.0
     * @param name
     * @return
     **/
    void aNewTransation(String name);




}
